/**
 * $Revision: 1.1 $
 * $Date: 2010/06/28 07:02:35 $
 *
 * Copyright (C) 2006 Jive Software. All rights reserved.
 *
 * This software is published under the terms of the GNU Lesser Public License (LGPL),
 * a copy of which is included in this distribution.
 */

package org.jivesoftware.spark.ui;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import javax.swing.undo.UndoManager;

import org.jivesoftware.spark.util.log.Log;
import org.jivesoftware.sparkimpl.settings.local.SettingsManager;

/**
 * This is implementation of ChatArea that should be used as the sendField
 * in any chat room implementation.
 */
public class ChatInputEditor extends ChatArea implements DocumentListener {

    private final UndoManager undoManager;
    private KeyStroke keyStroke;
    private int lastIndex;

    /**
     * Creates a new Default ChatSendField.
     */
    public ChatInputEditor() {
        undoManager = new UndoManager();
//        set
        this.setDragEnabled(true);
        this.getDocument().addUndoableEditListener(undoManager);
        Action undo = new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                undoManager.undo();
            }
        };

        keyStroke = KeyStroke.getKeyStroke('z', ActionEvent.CTRL_MASK);
        this.getInputMap().put(keyStroke, "undo");
        
        this.registerKeyboardAction(undo, KeyStroke.getKeyStroke(KeyEvent.VK_Z, KeyEvent.CTRL_MASK), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

        this.getDocument().addDocumentListener(this);

        this.addMouseListener(this);
    }

    public void insertUpdate(DocumentEvent e) {
        //    this.setCaretPosition(e.getOffset());
        this.requestFocusInWindow();
    }
    
    /**
     * Inserts an emotion icon into the current document.
     *
     * @param imageKey - the smiley representation of the image.( ex. :) )
     * @return true if the image was found, otherwise false.
     */
    public boolean insertImage(String imageKey) {
    	if(!forceEmoticons && !SettingsManager.getLocalPreferences().areEmoticonsEnabled()){
            return false;
        }
        final Document doc = getDocument();
        ImageIcon emotion = emoticonManager.getEmoticonImage(imageKey.toLowerCase());
        if (emotion == null) {
            return false;
        }

        setEditable(true);
        select(doc.getLength(), doc.getLength());
        insertIcon(emotion);
        emotion.setDescription(imageKey);
		
		
        return true;
    }
    /**
     * 发送消息之前将表情或者图片 
     * 转换为特殊定义的字符或者URL来进行传输
     * 
     * @return
     */
    public String getTransText(){
    	//初始转换表情/图片索引地址为0
    	lastIndex = 0;
    	emotionToKey();
    	return super.getText();
    }
    
    public void emotionToKey(){
    	StyledDocument sd = getStyledDocument();
    	for(int i= lastIndex;i<super.getText().length();i++){
    		Element tempElem = sd.getCharacterElement(i);
    		String str = tempElem.getName();
    		if(str.equals("icon")){
    			Icon icon = StyleConstants.getIcon(tempElem.getAttributes());
    			if(null!=icon){
    				String emotionKey = ((ImageIcon)icon).getDescription();
    				try {
    					lastIndex = i+emotionKey.length()+1;
						sd.remove(i,1);
						if(null!=emotionKey){
							sd.insertString(i,emotionKey,null);
						}
					} catch (BadLocationException e) {
						Log.error(e.getMessage(), e);
					}
    				emotionToKey();
    			}
    		}
    	}
    }
    

    public void setText(String str) {
        // Do nothing.
			try {
				insert(str);
			} catch (BadLocationException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			setEditable(true);
    }

    public void removeUpdate(DocumentEvent e) {
    }

    public void changedUpdate(DocumentEvent e) {
    }

    /**
     * Remove dependices when no longer in use.
     */
    public void close() {
        this.getDocument().removeDocumentListener(this);
        this.getDocument().removeUndoableEditListener(undoManager);
        this.removeMouseListener(this);
        this.getInputMap().remove(keyStroke);
    }

    /**
     * Disables the Chat Editor, rendering it to the system default
     * color.
     */
    public void showAsDisabled() {
        this.setEditable(false);
        this.setEnabled(false);

        clear();

        final Color disabledColor = (Color)UIManager.get("Button.disabled");

        this.setBackground(disabledColor);
    }

    /**
     * Enable the Chat Editor.
     */
    public void showEnabled() {
        this.setEditable(true);
        this.setEnabled(true);

        this.setBackground(Color.white);
    }

}